package com.shawn.appupdater.updater.net;

import android.os.Handler;
import android.os.Looper;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.concurrent.TimeUnit;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

/**
 * 具体实现网络请求和APK下载的操作
 */
public class OkHttpNetManager implements INetManager {

    private static OkHttpClient mOkhttpClient;
    // 因为要执行更新UI的操作，这里是异步线程，所以需要创建一个handler
    public Handler mHandler = new Handler(Looper.getMainLooper());

    static {
        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        // 设置服务器超时时间
        builder.connectTimeout(15, TimeUnit.SECONDS);
        mOkhttpClient = builder.build();
    }

    @Override
    public void get(String url, final INetCallBack callBack) {
        Request.Builder builder = new Request.Builder();
        Request request = builder.url(url).get().build();
        Call call = mOkhttpClient.newCall(request);
        // 同步操作
//        call.execute();
        // 异步操作
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, final IOException e) {
                // 请求失败
                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        callBack.failed(e);
                    }
                });
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                // 请求成功
                // 请求结果
                try {
                    final String result = response.body().string();
                    mHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            callBack.success(result);
                        }
                    });
                } catch (Throwable e) {
                    // 在网络请求过程中可能存在异常，所以用try catch捕捉，并传出
                    e.printStackTrace();
                    callBack.failed(e);
                }
            }
        });
    }

    @Override
    public void download(String url, final File targetFile, final INetDownloadCallBack callBack) {
        if (!targetFile.exists()) {
            targetFile.getParentFile().mkdirs();
        }

        Request.Builder builder = new Request.Builder();
        final Request request = builder.url(url).get().build();
        Call call = mOkhttpClient.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {

            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {

                InputStream inputStream = null;//输入流
                OutputStream outputStream = null;//输出流
                try {

                    inputStream = response.body().byteStream();// 从请求结果获取输入流
                    outputStream = new FileOutputStream(targetFile);

                    byte[] buffer = new byte[8 * 1024];
                    long currentLen = 0;
                    int bufferLen = 0;
                    final long totalLen = response.body().contentLength();// 请求内容的字节总长度

                    while ((bufferLen = inputStream.read(buffer)) != -1) {
                        outputStream.write(buffer, 0, bufferLen);
                        outputStream.flush();
                        // 记录当前写了多少个字节
                        currentLen += bufferLen;

                        // 刷新进度
                        final long finalCurrentLen = currentLen;
                        mHandler.post(new Runnable() {
                            @Override
                            public void run() {
                                int progress = (int) (finalCurrentLen * 1.0f / totalLen * 100);
                                callBack.progress(progress);
                            }
                        });

                        try {
                            targetFile.setExecutable(true, false);
                            targetFile.setReadable(true, false);
                            targetFile.setReadable(true, false);
                        } catch (Exception e) {
                            e.printStackTrace();
                        } finally {

                        }
                    }
                    mHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            callBack.success(targetFile);
                        }
                    });

                } catch (Throwable throwable) {
                    callBack.failed(throwable);
                } finally {
                    if (inputStream != null) {
                        inputStream.close();
                    }
                    if (outputStream != null) {
                        outputStream.close();
                    }
                }


            }
        });
    }
}
